import tkinter as tk
from tkinter import ttk, messagebox
import time
import threading

class ClapAnimation:
    """拍手动画组件"""
    def __init__(self, parent):
        self.parent = parent
        self.canvas = tk.Canvas(parent, width=200, height=150, bg="white", highlightthickness=0)
        self.canvas.grid(row=0, column=0, pady=10)  # 改用grid布局
        
        # 初始化手掌位置
        self.left_hand = self.canvas.create_oval(30, 50, 80, 100, fill="lightblue")
        self.right_hand = self.canvas.create_oval(120, 50, 170, 100, fill="lightblue")
        self.clapping = False

    def start_clap(self):
        """开始拍手动画"""
        if not self.clapping:
            self.clapping = True
            threading.Thread(target=self._animate, daemon=True).start()

    def stop_clap(self):
        """停止拍手动画"""
        self.clapping = False

    def _animate(self):
        """拍手动画逻辑"""
        positions = [
            (30, 50, 80, 100, 120, 50, 170, 100),  # 初始位置
            (50, 50, 100, 100, 100, 50, 150, 100),  # 中间位置（拍手）
            (30, 50, 80, 100, 120, 50, 170, 100)   # 回到初始位置
        ]
        
        while self.clapping:
            for pos in positions:
                if not self.clapping:
                    break
                # 更新手掌位置
                self.canvas.coords(self.left_hand, pos[0], pos[1], pos[2], pos[3])
                self.canvas.coords(self.right_hand, pos[4], pos[5], pos[6], pos[7])
                self.parent.update_idletasks()
                time.sleep(0.1)


class SevenClapGame:
    def __init__(self, root):
        self.root = root
        self.root.title("逢七拍手游戏（带动作演示）")
        self.root.geometry("900x600")
        self.root.resizable(True, True)

        # 创建主框架
        main_frame = ttk.Frame(root)
        main_frame.pack(fill="both", expand=True, padx=10, pady=5)

        # 左侧控制面板
        control_frame = ttk.LabelFrame(main_frame, text="控制区")
        control_frame.pack(side="left", fill="y", padx=5, pady=5)

        # 范围设置
        ttk.Label(control_frame, text="起始数字:").grid(row=0, column=0, padx=5, pady=5, sticky="w")
        self.start_var = tk.StringVar(value="1")
        ttk.Entry(control_frame, textvariable=self.start_var, width=10).grid(row=0, column=1, padx=5, pady=5)

        ttk.Label(control_frame, text="结束数字:").grid(row=1, column=0, padx=5, pady=5, sticky="w")
        self.end_var = tk.StringVar(value="100")
        ttk.Entry(control_frame, textvariable=self.end_var, width=10).grid(row=1, column=1, padx=5, pady=5)

        # 动作控制按钮
        ttk.Button(control_frame, text="开始分析", command=self.analyze).grid(row=2, column=0, columnspan=2, padx=5, pady=10)
        ttk.Button(control_frame, text="逐个演示", command=self.demo_one_by_one).grid(row=3, column=0, columnspan=2, padx=5, pady=5)
        ttk.Button(control_frame, text="停止演示", command=self.stop_demo).grid(row=4, column=0, columnspan=2, padx=5, pady=5)

        # 当前数字显示
        self.current_num_var = tk.StringVar(value="当前数字：--")
        ttk.Label(control_frame, textvariable=self.current_num_var, font=("Arial", 12)).grid(row=5, column=0, columnspan=2, padx=5, pady=20)

        # 拍手动画区域
        ttk.Label(control_frame, text="拍手动作演示：").grid(row=6, column=0, columnspan=2, padx=5, pady=5)
        # 创建动画容器，使用grid布局
        anim_container = ttk.Frame(control_frame)
        anim_container.grid(row=7, column=0, columnspan=2, padx=5, pady=5)
        self.clap_anim = ClapAnimation(anim_container)

        # 统计信息区域
        stats_frame = ttk.LabelFrame(control_frame, text="统计信息")
        stats_frame.grid(row=8, column=0, columnspan=2, padx=5, pady=10, sticky="nsew")
        
        self.total_var = tk.StringVar(value="总数字数：--")
        self.clap_count_var = tk.StringVar(value="拍手数字数：--")
        self.rate_var = tk.StringVar(value="拍手比例：--")
        
        ttk.Label(stats_frame, textvariable=self.total_var).pack(anchor="w", padx=5, pady=2)
        ttk.Label(stats_frame, textvariable=self.clap_count_var).pack(anchor="w", padx=5, pady=2)
        ttk.Label(stats_frame, textvariable=self.rate_var).pack(anchor="w", padx=5, pady=2)

        # 右侧结果区域
        result_frame = ttk.Frame(main_frame)
        result_frame.pack(side="right", fill="both", expand=True, padx=5, pady=5)

        # 详细列表标签页
        self.list_frame = ttk.LabelFrame(result_frame, text="详细列表")
        self.list_frame.pack(fill="both", expand=True)
        
        # 列表滚动条
        scrollbar = ttk.Scrollbar(self.list_frame)
        scrollbar.pack(side="right", fill="y")
        
        # 列表视图
        columns = ("数字", "是否拍手", "原因")
        self.tree = ttk.Treeview(self.list_frame, columns=columns, show="headings", yscrollcommand=scrollbar.set)
        for col in columns:
            self.tree.heading(col, text=col)
            self.tree.column(col, width=150, anchor="center")
        self.tree.pack(side="left", fill="both", expand=True)
        scrollbar.config(command=self.tree.yview)

        # 演示控制变量
        self.demo_running = False
        self.clap_numbers = []

    def is_clap_number(self, num):
        """判断是否需要拍手"""
        return '7' in str(num) or num % 7 == 0

    def get_reason(self, num):
        """获取拍手原因"""
        reasons = []
        if '7' in str(num):
            reasons.append("含数字7")
        if num % 7 == 0:
            reasons.append("7的倍数")
        return " + ".join(reasons) if reasons else "无"

    def analyze(self):
        """分析并展示结果"""
        # 清空之前的结果
        for item in self.tree.get_children():
            self.tree.delete(item)

        # 获取输入范围
        try:
            start = int(self.start_var.get())
            end = int(self.end_var.get())
            if start > end:
                start, end = end, start
            if start < 1:
                raise ValueError("起始数字不能小于1")
        except ValueError as e:
            messagebox.showerror("输入错误", f"请输入有效的数字范围：{str(e)}")
            return

        # 计算结果
        self.clap_numbers = []
        all_numbers = range(start, end + 1)
        total = len(all_numbers)
        
        for num in all_numbers:
            is_clap = self.is_clap_number(num)
            reason = self.get_reason(num)
            self.tree.insert("", "end", values=(num, "是" if is_clap else "否", reason))
            if is_clap:
                self.clap_numbers.append(num)

        # 更新统计信息
        clap_count = len(self.clap_numbers)
        rate = clap_count / total if total > 0 else 0
        self.total_var.set(f"总数字数：{total}")
        self.clap_count_var.set(f"拍手数字数：{clap_count}")
        self.rate_var.set(f"拍手比例：{rate:.2%}")

    def demo_one_by_one(self):
        """逐个演示数字，遇到拍手数字时触发动画"""
        if not self.clap_numbers:
            messagebox.showwarning("提示", "请先点击【开始分析】生成数据")
            return

        self.demo_running = True
        threading.Thread(target=self._run_demo, daemon=True).start()

    def stop_demo(self):
        """停止演示"""
        self.demo_running = False
        self.clap_anim.stop_clap()
        self.current_num_var.set("当前数字：--")

    def _run_demo(self):
        """演示逻辑"""
        start = int(self.start_var.get())
        end = int(self.end_var.get())
        if start > end:
            start, end = end, start

        for num in range(start, end + 1):
            if not self.demo_running:
                break
                
            # 更新当前数字显示
            self.current_num_var.set(f"当前数字：{num}")
            
            # 判断是否需要拍手
            if self.is_clap_number(num):
                self.clap_anim.start_clap()  # 开始拍手动画
                time.sleep(1)  # 拍手持续时间
                self.clap_anim.stop_clap()   # 停止拍手动画
            else:
                time.sleep(0.3)  # 非拍手数字停留时间

        # 演示结束
        if self.demo_running:
            self.current_num_var.set("演示结束")
            self.demo_running = False


if __name__ == "__main__":
    root = tk.Tk()
    app = SevenClapGame(root)
    root.mainloop()